{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    ".. _nb_discrete:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Discrete Variable Problem\n",
    "\n",
    "Mostly, *pymoo* was made for continuous problems, but of course, other variable types can be used as well. The genetic algorithm is a very modular class, and by modifying the sampling, crossover, and mutation (in some cases also repair), different kinds of variable types can be used (also more complicated ones such as tree, graph, ...)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the following we consider an easy optimization problem where only integer variables are supposed to be used."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "from pymoo.algorithms.soo.nonconvex.ga import GA\n",
    "from pymoo.core.problem import Problem\n",
    "from pymoo.operators.crossover.sbx import SBX\n",
    "from pymoo.operators.mutation.pm import PM\n",
    "from pymoo.operators.repair.rounding import RoundingRepair\n",
    "from pymoo.operators.sampling.rnd import IntegerRandomSampling\n",
    "from pymoo.optimize import minimize\n",
    "\n",
    "\n",
    "class MyProblem(Problem):\n",
    "\n",
    "    def __init__(self):\n",
    "        super().__init__(n_var=2, n_obj=1, n_ieq_constr=1, xl=0, xu=10, vtype=int)\n",
    "\n",
    "    def _evaluate(self, x, out, *args, **kwargs):\n",
    "        out[\"F\"] = - np.min(x * [3, 1], axis=1)\n",
    "        out[\"G\"] = x[:, 0] + x[:, 1] - 10\n",
    "\n",
    "\n",
    "problem = MyProblem()\n",
    "\n",
    "method = GA(pop_size=20,\n",
    "            sampling=IntegerRandomSampling(),\n",
    "            crossover=SBX(prob=1.0, eta=3.0, vtype=float, repair=RoundingRepair()),\n",
    "            mutation=PM(prob=1.0, eta=3.0, vtype=float, repair=RoundingRepair()),\n",
    "            eliminate_duplicates=True,\n",
    "            )\n",
    "\n",
    "res = minimize(problem,\n",
    "               method,\n",
    "               termination=('n_gen', 40),\n",
    "               seed=1,\n",
    "               save_history=True\n",
    "               )\n",
    "\n",
    "print(\"Best solution found: %s\" % res.X)\n",
    "print(\"Function value: %s\" % res.F)\n",
    "print(\"Constraint violation: %s\" % res.CV)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "from pymoo.util import plotting\n",
    "\n",
    "_X = np.row_stack([a.pop.get(\"X\") for a in res.history])\n",
    "feasible = np.row_stack([a.pop.get(\"feasible\") for a in res.history])[:, 0]\n",
    "\n",
    "plotting.plot(_X[feasible], _X[np.logical_not(feasible)], res.X[None,:]\n",
    "              , labels=[\"Feasible\", \"Infeasible\", \"Best\"])"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
